【アップデート】S3でACLを無効化できるようになりました #reinvent
re:Invent 2021 の期間中に登場した以下アップデートを紹介します。
どんなアップデート?
S3バケットに 『ACL無効』 の設定を付与できます。 この設定は新規バケット作成時にも設定可能、既存バケットに対しても追加で設定可能です。
何が嬉しいの?
ひとことで言うと
「ACLを捨てて、全部ポリシーで管理したいなああぁ…」 を叶えてくれます
詳しく
S3 は歴史あるサービスです。 当初は S3バケットに対するアクセス制御の手段は ACL のみでした。 S3バケットはデフォルトでプライベートです。 そのため 他アカウント(もしくはパブリック)からのアクセス許可は ACL で実現しました。
その後 IAM が提供されて、アクセス制御の手段として ポリシー(IAMユーザーポリシーやバケットポリシーなど) が追加されました。
つまり現在、 S3バケットに対するアクセス制御は ACL と ポリシーを両方考慮 する必要があります。
– 画像: アクセス管理の概要 - Amazon Simple Storage Service
これが結構大変です。 『ポリシーではパブリックにしていないけど、ACLでパブリック設定になっていた…』 ケース※ がよく出てきます。
さらにいうと、ポリシーのほうがより柔軟です。 ACLではできない粒度のアクセス制御を実現できます。
こういった背景から 「ACLを捨てて、全部ポリシーで管理したいなああぁ…」 と願う人たちが出てきました。 その願いを叶える機能が今回のアップデート 『ACL無効の設定』 です。
※『意図しない公開』を防ぐために パブリックアクセスブロック機能 も 2018年に追加されています。これも ACL の制限を行うために役立ちます。
仕組み
ひとことで言うと
オブジェクトオーナーシップ設定値 に
BucketOwnerEnforced
を定めることで、
全てのオブジェクトを 『バケットを所有しているアカウント』のもの とできます。
『詳しく』の前に
ここから先は ACL が前提知識となってきます。 もし『ACL ってそもそも何だっけ?』となっている方がいらっしゃったら、以下ブログを参照ください。
(『そもそも ACL を知る必要が無くなる、素晴らしいアップデート』という捉え方もできますね)
詳しく
もともと S3バケットに対して オブジェクトオーナーシップ設定 を付与できていました。 (この設定自体は比較的新しく、2020年に実装されています)
この設定はバケットにアップロードされたオブジェクトの所有権を制御するための設定です。 今までは以下 2つの設定値が選択できていました。
- オブジェクトライター(ObjectWriter)
- 従来どおりの挙動です
- 『オブジェクトライター(アップロードしたアカウント)』がオブジェクト所有者となります
- バケット所有者優先(BucketOwnerPreferred)
bucket-owner-full-control
既定ACLを指定した場合、 『バケットを所有しているアカウント』がオブジェクト所有者です- それ以外の場合、 『オブジェクトライター』がオブジェクト所有者です
※ 上図キャプチャ(2021/12/02時点)では『希望するバケット所有者』となっていますが、 正しい解釈としては『バケット所有者優先』だと思います
この設定値に BucketOwnerEnforced を新たに定められるようになりました。 これが今回のアップデートです 。
※前提として 『バケットACLはデフォルトである』必要があります。バケットACLを付与している状態ではこの設定は適用できません。
BucketOwnerEnforced
を定めることで、
全てのオブジェクトは 『バケットを所有しているアカウント』 のものとなります。
今までは ACL次第で
オブジェクトの所有者を他アカウントにすることができていました。
BucketOwnerEnforced
によって、それができなくなります。
つまり ACLによるアクセス制御(例えば他アカウントに意図せず公開されてないか) を意識する必要がなくなります。 これによって、バケットとオブジェクトへのアクセス制御を ポリシー(IAMユーザーポリシーやバケットポリシーなど)で集中管理 できます。
試してみる
試したこと
3つのバケット(図の右側)を作成します。
それぞれオーナーシップの設定を ObjectWriter, BucketOwnerPreferred, BucketOwnerEnforced
としています。
そしてそれぞれのバケットに対して 2つの操作(操作1, 操作2
) でオブジェクトをアップロードします。
- 操作1: ACLはデフォルトの設定でオブジェクトアップロード
- 操作2: ACLは
bucket-owner-full-control
の設定でオブジェクトアップロード
『それぞれのバケット』にある『それぞれのオブジェクト』の ACL上の所有者を確認します。
結果
以下のような結果になりました。
オブジェクト(操作1) | オブジェクト(操作2) | |
---|---|---|
S3バケット#1(ObjectWriter) | Writer 所有 | Writer と Owner 所有 |
S3バケット#2(BucketOwnerPreferred) | Writer 所有 | Owner 所有 |
S3バケット#3(BucketOwnerEnforced) | Owner 所有 | Owner 所有 |
今回アップデートで追加された設定値 BucketOwnerEnforced
の結果から、
『特別なACLを付ける/付けない』に関わらず
他アカウントからアップロードされたオブジェクトは
全て バケットのオーナー所有になる ことを再確認できました。
おわりに
以上、S3アクセス制御周りの新機能の紹介でした。 これから新規に作成するS3バケットには必ず設定したい機能だと感じました。
既存バケットにも適用できますがワークロードへの影響を考慮しましょう。 事前に ACL は使わずに ポリシーで運用できていることを確認した上で、 移行すると良いと思います。
参考
- Amazon S3 Object Ownership can now disable access control lists to simplify access management for data in S3
- New – Simplify Access Management for Data Stored in Amazon S3 | AWS News Blog
- Controlling ownership of objects and disabling ACLs for your bucket - Amazon Simple Storage Service
- Document history - Amazon Simple Storage Service
補足
ライターアカウントから『オーナーアカウントのS3バケット』へアクセスするために設定したバケットポリシー
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Statement1", "Principal": {"AWS": "${ライターアカウントのAWSアカウントID}"}, "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::${バケット名}/*" } ] }
操作1(ACLはデフォルトでオブジェクトアップロード)のコマンド
profile_writer="${ライターアカウントのプロファイル}" bucket="${オーナーアカウントにあるバケット}" file_path="./test.txt" key="test-from-write-account-default.txt" aws s3api put-object --profile "${profile_writer}" --output yaml \ --bucket "${bucket}" --key "${key}" --body "${file_path}"
操作2(ACLは bucket-owner-full-control でオブジェクトアップロード)のコマンド
profile_writer="${ライターアカウントのプロファイル}" bucket="${オーナーアカウントにあるバケット}" file_path="./test.txt" key="test-from-write-account-with-acl.txt" aws s3api put-object --profile "${profile_writer}" --output yaml \ --bucket "${bucket}" --key "${key}" --body "${file_path}" \ --acl bucket-owner-full-control
結果の確認コマンド
profile_writer="${ライターアカウントのプロファイル}" profile_owner="${オーナーアカウントのプロファイル}" bucket="${オーナーアカウントにあるバケット}" key="test-from-write-account-default.txt" # key="test-from-write-account-with-acl.txt" # オーナーアカウントからオブジェクトの ACL設定をチェック echo "## check from bucket owner account" aws s3api get-object-acl --profile "${profile_owner}" --output yaml \ --bucket "${bucket}" --key "${key}" # ライターアカウントからオブジェクトの ACL設定をチェック echo "## check from object writer account" aws s3api get-object-acl --profile "${profile_writer}" --output yaml \ --bucket "${bucket}" --key "${key}"